﻿/**************************************************************************
创建时间:	2019/5/13
作	  者:	张存
邮 	  箱:	zhangcunliang@126.com

描	述：
记	录：
***************************************************************************/
using ASmile.DBModel;
using ASmile.Extend;
using ASmile.Helpers;
using ASmile.ORM.Entitys;
using ASmile.Win.ADSearch;
using ASmile.Win.Controls;
using ASmile.Win.Forms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;

namespace ASmile.Win
{
    public partial class FrmBase : DockContent, IFormContainer
    {
        public FrmBase()
        {
            InitializeComponent();
        }

        #region 属性

        /// <summary>
        /// 是否管理员
        /// </summary>
        [Browsable(false)]
        protected internal virtual bool IsManager { get { return LoginUser.IsManager != null && LoginUser.IsManager.Value; } }

        string _ContainerName;
        /// <summary>
        /// 窗体对象标识，默认为类型全称
        /// </summary>
        [Browsable(false)]
        public virtual string ContainerName
        {
            get
            {
                if (_ContainerName.IsEmpty())
                {
                    _ContainerName = this.GetType().ToString();
                }
                return _ContainerName;
            }
            protected set
            {
                _ContainerName = value;
            }
        }
        /// <summary>
        /// 自动初始化GridView
        /// </summary>
        [Description("自动初始化GridView")]
        public bool AutoInitGridView { set; get; } = true;
        /// <summary>
        /// 控件权限参数
        /// </summary>
        [Browsable(false)]
        public string ControlRightsArgs { set; get; }
        /// <summary>
        /// 是否初始化为默认样式
        /// </summary>
        [Description("是否初始化为默认样式,字体，等")]
        public bool InitDefaultStyle { set; get; } = true;
        /// <summary>
        /// 运行窗体的参数，由角色菜单配置
        /// </summary>
        [Browsable(false)]
        public string MenuArgs { get; internal set; }

        #endregion

        private void FrmBase_Load(object sender, EventArgs e)
        {
            //“HideOnClose”属性很重要，该属性一般设置为True，
            //就是指你关闭窗口时，窗体只是隐藏而不是真的关闭。
            this.HideOnClose = false;

            InitStyle();

            if (!DesignMode)
            {
                if (!Config.Settings.FormIcon.IsEmpty())
                {
                    if (File.Exists(Config.Settings.FormIcon))
                    {
                        this.Icon = new Icon(Config.Settings.FormIcon);
                    }
                }

                InitLabelMsg();
                InitTabHeadMenu();
                InitKeyDown();
                InitAutoGridView();
                this.InitControlRights();
                //if (IsManager)
                //{
                //    this.FindControl(FindToolBar, FIndMatch);
                //    bool FindToolBar(Control c)
                //    {
                //        if (c is ToolStrip ts)
                //        { 

                //        }
                //        return false;
                //    }
                //    bool FIndMatch(Control c)
                //    {
                //        return c is ToolStrip;
                //    }
                //}
                //else
                //{

                //}
            }
        }

        #region 初始化样式

        void InitStyle()
        {
            if (!InitDefaultStyle) return;
            this.Font = new System.Drawing.Font("微软雅黑", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
        }

        #endregion

        #region 消息框

        /// <summary>
        /// 打开正常对话框(将来改造多语言准备)
        /// </summary>
        protected void ShowMessageBox(string msg)
        {
            MessageBox.Show(msg);
        }
        /// <summary>
        /// 消息提示
        /// </summary>
        protected LabelMessage MsgTips { set; get; }
        /// <summary>
        /// 初始化提示框
        /// </summary>
        void InitLabelMsg()
        {
            MsgTips = new LabelMessage();
            MsgTips.SetControlHost(this);
        }
        /// <summary>
        /// 显示消息
        /// </summary>
        public void ShowMessage(string msg)
        {
            if (this.InvokeRequired)
            {
                Action<string> InvokeHandle = ShowMessage;
                this.Invoke(InvokeHandle, msg);
            }
            else
            {
                MsgTips.ShowTips(msg);
            }
        }
        /// <summary>
        /// 询问提示框,点击OK 返回true
        /// </summary>
        public bool ShowQuestion(string msg, string caption, params object[] msgArgs)
        {
            string msgText = string.Format(msg, msgArgs);
            DialogResult r = MessageBox.Show(msgText, caption, MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button2);
            return r == DialogResult.OK ? true : false;
        }
        ///// <summary>
        ///// 打开选择treeview对话框
        ///// </summary>
        ///// <param name="InitTreeHandle">初始化treeview的方法</param>
        ///// <param name="OnSelected">选中后触发校验</param>
        //public bool ShowTreeSelect(Action<TreeView> InitTreeHandle, Func<TreeView, ApiResult> OnSelected, string title = null)
        //{
        //    FrmSelectTree frm = new FrmSelectTree();
        //    frm.InitTreeHandle = InitTreeHandle;
        //    frm.OnSelected = OnSelected;
        //    if (!title.IsEmpty())
        //    {
        //        frm.Text = title;
        //    }
        //    return frm.ShowDialog() == DialogResult.OK;
        //}

        #endregion

        #region 透明层遮罩等待

        //OpaqueLayer _OpaqueLayer;

        ///// <summary>
        ///// 遮罩层控件
        ///// </summary>
        //public OpaqueLayer OpaqueLayer
        //{
        //    get
        //    {
        //        if (_OpaqueLayer == null)
        //        {
        //            _OpaqueLayer = new OpaqueLayer();
        //        }
        //        return _OpaqueLayer;
        //    }
        //}

        public void StartWorking(Action WorkHandle, Action WorkAfterHandle = null)
        {
            StartWorking(125, 0, (layer) => WorkHandle(), WorkAfterHandle);
        }

        public void StartWorking(int progressMax, Action<IOpaqueLayer> WorkHandle, Action WorkAfterHandle = null)
        {
            StartWorking(125, progressMax, WorkHandle, WorkAfterHandle);
        }

        /// <summary>
        /// 使用遮罩开始长时间工作
        /// </summary>
        public void StartWorking(byte alpha, int progressMax, Action<IOpaqueLayer> WorkHandle, Action WorkAfterHandle = null)
        {
            OpaqueLayer opaLayer = new OpaqueLayer(alpha);
            opaLayer.ShowLayer(this, progressMax);
            Task.Factory.StartNew(() =>
            {
                this.Invoke(WorkHandle, opaLayer);
                //WorkHandle(opaLayer);
                this.Invoke(new Action(After));
                void After()
                {
                    opaLayer.HideOpaqueLayer();
                    opaLayer.Dispose();
                    if (WorkAfterHandle != null)
                    {
                        Invoke(WorkAfterHandle);
                    }
                }
            });
        }

        #endregion

        #region 关闭,关闭其它,关闭所有窗体

        void InitTabHeadMenu()
        {
            tsmiCloseForm.Click += TsmiCloseForm_Click;

            tsmiColeOtherForm.Click += TsmiCloseOtherForm_Click;

            tsmiCloseAllForm.Click += TsmiCloseAllForm_Click;
        }

        /// <summary>
        /// 关闭当前窗体
        /// </summary>
        protected void TsmiCloseForm_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        /// <summary>
        /// 关闭其它窗体
        /// </summary>
        protected void TsmiCloseOtherForm_Click(object sender, EventArgs e)
        {
            IDockContent[] documents = DockPanel.DocumentsToArray();
            foreach (IDockContent content in documents)
            {
                if (!content.Equals(this))
                {
                    content.DockHandler.Close();
                }
            }
        }
        /// <summary>
        /// 关闭tab标签中的所有窗体
        /// </summary>
        protected void TsmiCloseAllForm_Click(object sender, EventArgs e)
        {
            IDockContent[] documents = DockPanel.DocumentsToArray();
            foreach (IDockContent content in documents)
            {
                content.DockHandler.Close();
            }
        }

        #endregion

        #region 高级搜索

        /// <summary>
        /// 实现高级搜索
        /// </summary>
        /// <param name="sql">SqlBuilder对象</param>
        /// <param name="SearchAfter">搜索框点击确认后的处理方法</param>
        protected internal void ADSearch(List<AdSearchDetail> searchList, Action SearchAfter, DataGridView dgv = null)
        {
            string dgvName = dgv?.Name;
            if (dgvName.IsEmpty()) dgvName = "dgv";
            FrmADSearch frm = new FrmADSearch(searchList, dgvName);
            if (frm.ShowSearch(this))
            {
                SearchAfter();
            }
        }
        protected internal void ADSearch(ArgPageData searchArg, Action SearchAfter, DataGridView dgv = null)
        {
            ADSearch(searchArg.AdSearchList, SearchAfter, dgv);
        }
        ///// <summary>
        ///// 通过BLL对象高级搜索(只进行AdSearch赋值) , SearchAfter: 为绑定数据源的方法
        ///// </summary>
        //protected internal void ADSearch(BLLBase bll, Action SearchAfter, DataGridView dgv = null)
        //{
        //    ADSearch(bll.ADSqlBuilder, SearchAfter, dgv);
        //}

        #endregion

        #region 共通快捷键
        /// <summary>
        /// 初始化全局快捷键
        /// </summary>
        void InitKeyDown()
        {
            if (IsManager)
            {
                KeyDown += Form_KeyDown;
                KeyPreview = true;
            }
        }

        private void Form_KeyDown(object sender, KeyEventArgs e)
        {
            //模式窗体有时会隐藏到下层，此方法可移动窗体
            if (this.Modal)
            {
                if (Control.ModifierKeys == Keys.Control && e.KeyCode == Keys.Left)
                {
                    Left -= 10;
                }
                if (Control.ModifierKeys == Keys.Control && e.KeyCode == Keys.Right)
                {
                    Left += 10;
                }
                if (Control.ModifierKeys == Keys.Control && e.KeyCode == Keys.Up)
                {
                    Top -= 10;
                }
                if (Control.ModifierKeys == Keys.Control && e.KeyCode == Keys.Down)
                {
                    Top += 10;
                }
            }

            if (!IsManager) return; //以下为管理员
            if (Control.ModifierKeys == Keys.Control && e.KeyCode == Keys.Oemtilde)
            {
                //GridViewColumn
                FrmGridColumn frm = new FrmGridColumn();
                frm.MinimizeBox = false;
                frm.Owner = this;
                frm.ShowDialog();
                return;
            }
            if (Control.ModifierKeys == Keys.Control && e.KeyCode == Keys.D1)
            {
                FrmGridCombox frm = new FrmGridCombox();
                frm.MinimizeBox = false;
                frm.Owner = this;
                frm.ShowDialog();
                return;
            }
            if (Control.ModifierKeys == Keys.Control && e.KeyCode == Keys.D2)
            {
                FrmCfgPrint frm = new FrmCfgPrint();
                frm.MinimizeBox = false;
                frm.Owner = this;
                frm.ShowDialog();
                return;
            }
        }

        /// <summary>
        /// 设置指定GridView 的数据源生成Insert SQL 脚本
        /// </summary>
        protected virtual void SetCopyInsertSql<T>(DataGridView dgv, Keys key, params string[] ignoreFields)
            where T : class, new()
        {
            if (!IsManager) return;

            KeyDown -= OnKeyDown;
            KeyDown += OnKeyDown;

            void OnKeyDown(object sender, KeyEventArgs e)
            {
                if (!IsManager) return;
                if (ModifierKeys == Keys.Control && e.KeyCode == key)
                {
                    var rList = dgv.DataSource as List<T>;
                    List<string> ignoreFieldList = new List<string>();
                    if (ignoreFieldList?.Count > 0)
                    {
                        ignoreFieldList.AddRange(ignoreFields);
                    }
                    Type type = typeof(T);
                    var pros = type.GetProperties();
                    foreach (var item in pros)
                    {
                        var attr = ReflectionHelper.GetCustomAttribute<EntityAttribute>(item);
                        if (attr.IsNotField)
                        {
                            ignoreFieldList.Add(item.Name);
                        }
                    }
                    var sql = SqlScriptTool.GetInsertSQL(rList, ignoreFieldList.ToArray());
                    Clipboard.SetText(sql.ToString());
                    //Clipboard.SetDataObject(sql.ToString());
                    MessageBox.Show("sql 脚本已经赋值到剪切板！");
                }
            }
        }
        /// <summary>
        /// 设置指定 GridView 默认 Ctrl+P 复制到剪切板
        /// </summary>
        protected virtual void SetCopyInsertSql<T>(DataGridView dgv)
            where T : class, new()
        {
            SetCopyInsertSql<T>(dgv, Keys.P);
        }

        #endregion

        #region 自动初始化GridView

        void InitAutoGridView()
        {
            if (AutoInitGridView)
            {
                this.InitGridView();
            }
        }

        #endregion

        #region 表格选择器（ComboxGrid）

        ComboxGrid _CoGrid;
        /// <summary>
        /// 表格选择器对象
        /// </summary>
        [Browsable(false)]
        public ComboxGrid CoBoxGrid
        {
            get
            {
                if (_CoGrid == null) _CoGrid = new ComboxGrid();
                return _CoGrid;
            }
        }
        /// <summary>
        /// 通过配置初始化表格选择器
        /// </summary>
        public ComboxGridArgs[] InitCoBoxGrid(params ArgInitCoBoxGrid[] args)
        {
            //CoBoxGrid.Clear();
            var r = this.InitCoBoxGrid(CoBoxGrid, args);
            return r;
        }
        /// <summary>
        /// 初始单个控件的 ComBoxGrid (如果多个,请使用 ArgInitCoBoxGrid[] 参数初始化,使用该方法会影响效率 )
        /// </summary>
        public ComboxGridArgs InitCoBoxGrid(EditText txt, Func<string, object> GetDataSource)
        {
            var arg = new ArgInitCoBoxGrid
            {
                Txt = txt,
                GetDataSource = GetDataSource
            };
            var r = InitCoBoxGrid(arg);
            return r?.First();
        }

        #endregion

        #region 反射创建窗体

        /// <summary>
        /// 创建form的方法，可自定义方式，如：spring
        /// </summary>
        /// <param name="name">name格式为：“类全名,程序集”</param>
        /// <returns>返回FrmBase</returns>
        protected virtual FrmBase CreateForm(string name)
        {
            var frm = ObjectFactory.GetObject<FrmBase>(name);
            return frm;

            //var frm = ReflectionHelper.CreateInstance<FrmBase>(name);
            //return frm;
        }

        #endregion

        #region 打印

        /// <summary>
        /// 当前窗口的打印配置
        /// </summary>
        internal List<Sys_PrintConfig> PrintConfigs { set; get; }

        protected void Print(object detailData, int printIndex, params object[] args)
        {
            PrintHelper.Print(this, detailData, args, printIndex);
        }

        protected void Print(object detailData, params object[] args)
        {
            //var formName = this.ContainerName;
            PrintHelper.Print(this, detailData, args, 0);
        }
        /// <summary>
        /// 指定索引打印参数
        /// </summary>
        protected void PrintArg(int printIndex, params object[] args)
        {
            //var formName = this.ContainerName;
            PrintHelper.Print(this, null, args, printIndex);
        }

        /// <summary>
        /// 仅打印参数,不包含明细数据
        /// </summary>
        protected void PrintArg(params object[] args)
        {
            //var formName = this.ContainerName;
            PrintHelper.Print(this, null, args, 0);
        }
        /// <summary>
        /// 通过参数配置打印
        /// </summary>
        protected void Print(PrintReportArg arg, int printIndex)
        {
            PrintHelper.Print(this, arg, printIndex);
        }

        #endregion

        /// <summary>
        /// 输入对话框
        /// </summary>
        public bool ShowInput(Func<string, ApiResult> SaveHandle, string title, string defaultStr = null)
        {
            FrmInput frm = new FrmInput(SaveHandle, defaultStr);
            if (!title.IsEmpty())
            {
                frm.Text = title;
            }
            return frm.ShowDialog() == DialogResult.OK;
        }
    }
}